using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;

namespace IsometricEngine {
    public enum RenderType { 
        NonIsoBitmap = 1 << 1, 
        Bitmap = 1 << 2, 
        Text = 1 << 3, 
        BitmapAndText = Bitmap & Text, 
        None = 0 
    }
    public class Renderable {
        protected const int tileHeight = 24;
        protected const int tileWidth = 24;
        protected const float textFrameWidth = .8f;
        protected const float textFrameHeight = .4f;
        protected const float textWidth = .8f;
        protected const float textHeight = .3f;

        protected static Vector2 screenSize;

        public bool enabled { get; set; }
        public RenderType renderType { get; set; }

        public Vector2 textPos { get; set; }
        public Rectangle textureSize = Rectangle.Empty;

        public string text { get; set; }

        public float textDepth { get; set; }
        
        public int textureID { get; set; }
        public int fontID { get; set; }

        public Color tint = Color.White;
        public List<Renderable> children = new List<Renderable>();
        public virtual Matrix transMatrix { get; set; }

        public Renderable() {
            enabled = true;
            transMatrix = Matrix.Identity;
            renderType = RenderType.Text;
            textDepth = 0;
            textureDepth = 0;
            textureID = 1;  //Default white texture
            fontID = 0;     //Standard font
            enabled = true;
            text = "";
            screenSize = RenderMngr.ScreenSize;
        }
        
        public float textureDepth {
            get { return (topDepth + bottomDepth) / 2; }
            set { topDepth = value; bottomDepth = value; }
        }

        public float topDepth { 
            get { return (topLeftDepth + topRightDepth) / 2; }
            set { topLeftDepth = value; topRightDepth = value; } 
        }
        public float bottomDepth {
            get { return (bottomLeftDepth + bottomRightDepth) / 2; }
            set { bottomLeftDepth = value; bottomRightDepth = value; }
        }
        
        public float topLeftDepth { get; set; }
        public float topRightDepth { get; set; }
        public float bottomLeftDepth { get; set; }
        public float bottomRightDepth { get; set; }

        //Probably unused.
        public static string wordWrap(string text, float width) {
            string output = "";
            text = text.Replace("\\r\\n", "\r\n");
            text = text.Trim();
            string[] split = text.Split(new string[] { " ", "\r", "\n", "\t" }, StringSplitOptions.RemoveEmptyEntries);
            float currentSize = 0;
            foreach (string s in split) {
                Vector2 size = RenderMngr.textSize(s, 0);
                if (size.X + currentSize > width) {
                    output += "\n" + s;
                    currentSize = size.X;
                } else {
                    output += " " + s;
                    currentSize += size.X;
                }
            }

            return output.Substring(1);
        }
        public int clipText(string input, ref string output, float width, float height, int linestart) {
            List<string> lines = new List<string>();
            int lineIndex = 0;
            lines.Add("");
            //We want to select lines from linestart until height
            input = input.Replace("\\n", "\n");
            input = input.Replace("\\r", "");
            input = input.Replace('\n', ' ');
            input = input.Replace('\r', ' ');
            string[] words = input.Split(' ');

            Vector2 lineSize = new Vector2();
            float spaceWidth = RenderMngr.textSize(" ", this.fontID).X;

            foreach (string word in words) {
                Vector2 wordSize = RenderMngr.textSize(word, this.fontID);
                if (lineSize.X + wordSize.X < width) { //
                    lines[lineIndex] += word + " ";
                    if (word.Contains("\r\n"))
                        lineSize.X = wordSize.X + spaceWidth;
                    else 
                        lineSize.X += wordSize.X + spaceWidth;
                } else {
                    lineIndex++;
                    lines.Add(word + " ");
                    lineSize.X = wordSize.X + spaceWidth;
                }
            }
            input = "";
            for (int i = linestart; i < lines.Count(); i++) {
                Vector2 size = RenderMngr.textSize(lines[i], this.fontID);
                if (size.Y + lineSize.Y < height) {
                    if (i != linestart) output += "\r\n";
                    output += lines[i];
                    lineSize.Y += size.Y;
                } else {
                    return 1;
                }
            }

            //Return 0 if no more above or below
            //Return 1 if more below
            return 0;
        }
    }
}
